package com.qiaofang.applet.service.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.qiaofang.applet.common.base.MongoBaseService;
import com.qiaofang.applet.common.context.QfContext;
import com.qiaofang.applet.common.context.QfContextHolder;
import com.qiaofang.applet.common.dto.AppointmentMessageRequest;
import com.qiaofang.applet.common.exception.BusinessException;
import com.qiaofang.applet.constants.MessageTypeEnum;
import com.qiaofang.applet.constants.ReceiverTypeEnum;
import com.qiaofang.applet.constants.RemindModeEnum;
import com.qiaofang.applet.service.member.domain.Appointment;
import com.qiaofang.applet.service.member.domain.Employee;
import com.qiaofang.applet.service.member.repository.AppointmentRepository;
import com.qiaofang.applet.service.member.repository.EmployeeRepository;
import com.qiaofang.applet.service.member.service.AppointmentService;
import com.qiaofang.applet.service.member.service.EmployeeService;
import com.qiaofang.applet.service.member.service.dto.*;
import com.qiaofang.applet.service.member.service.mapstruct.AppointmentMapper;
import com.qiaofang.applet.service.other.domain.Corporation;
import com.qiaofang.applet.service.other.domain.EmployeeLabel;
import com.qiaofang.applet.service.other.service.CorporationService;
import com.qiaofang.applet.service.other.util.DateTypeUtil;
import com.qiaofang.applet.service.property.domain.FirsthandEstate;
import com.qiaofang.applet.service.property.domain.Property;
import com.qiaofang.applet.service.property.repository.FirsthandEstateRepository;
import com.qiaofang.applet.service.property.repository.PropertyRepository;
import com.qiaofang.applet.service.property.service.CommonService;
import com.qiaofang.applet.service.property.service.dto.NewEntrustSimpleDto;
import com.qiaofang.applet.service.property.service.dto.ShowEmpUuidDto;
import com.qiaofang.core.gatewayclient.GatewayTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.qiaofang.applet.constants.SignConstants.APPOINTMENT_MESSAGE_API;

/**
 * @author daiyuxiang
 */
@Slf4j
@Service
public class AppointmentServiceImpl extends MongoBaseService<Appointment, String> implements AppointmentService {

    private final AppointmentRepository repository;

    public static final String BEGIN_TIME = " 00:00:00";
    public static final String END_TIME = " 23:59:59";

    private static final String V20_SENT_SINGLE_MESSAGE_API = "/api/jedioperation/op/message/createMessage";

    public static final String MSG_TRIGGER_SYS = "系统";

    public static final String MESSAGE_SUB_TITLE = "官网小程序";

    public static final String NEW_HOUSE = "新房";

    @Autowired
    public AppointmentServiceImpl(AppointmentRepository repository) {
        super(repository);
        this.repository = repository;
    }

    @Autowired
    private AppointmentMapper appointmentMapper;

    @Autowired
    private EmployeeRepository employeeRepository;

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private CorporationService corporationService;

    @Autowired
    private FirsthandEstateRepository firsthandEstateRepository;

    @Autowired
    private PropertyRepository propertyRepository;

    @Autowired
    private GatewayTemplate gatewayTemplate;

    @Autowired
    private CommonService commonService;

    private static RestTemplate restTemplate = new RestTemplate();


    @Override
    public List<AppointmentEmpListDto> getEmpList(AppointmentEmpQueryDto queryDto) {
        String employeeUniqueUuid = queryDto.getEmployeeUniqueUuid();
        List<Employee> employeeList = new LinkedList<>();
        List<String> empUniqueUuidList = new LinkedList<>();
        if (StringUtils.isEmpty(employeeUniqueUuid)) {
            String businessUuid = queryDto.getBusinessUuid();
            Integer businessType = queryDto.getBusinessType();
            ShowEmpUuidDto empUuidDto;
            if (businessType == 1) {
                empUuidDto = employeeService.getEmployeeUuidDtoByFirsthand(businessUuid);
            } else {
                if (commonService.isV20Corporation()) {
                    empUuidDto = employeeService.getV20EmployeeUuidDtoByProperty(businessUuid);
                }else {
                    empUuidDto = employeeService.getEmployeeUuidDtoByProperty(businessUuid);
                }
            }

            String companyUuid = empUuidDto.getCompanyUuid();
            List<String> employeeUuidList = empUuidDto.getEmployeeUuidList();
            String fixedEmployeeUuid = empUuidDto.getFixedEmployeeUuid();

            //获取固定展示位经纪人
            Employee fixedEmployee = employeeRepository.findByCompanyUuidAndEmployeeUuid(companyUuid, fixedEmployeeUuid);
            if (employeeUuidList.contains(fixedEmployeeUuid)) {
                employeeUuidList.remove(fixedEmployeeUuid);
            }
            empUniqueUuidList.add(companyUuid + "_" + fixedEmployeeUuid);
            if (fixedEmployee == null && StringUtils.isNotEmpty(empUuidDto.getEmployeeUuid1())) {
                fixedEmployee = employeeRepository.findByCompanyUuidAndEmployeeUuid(companyUuid, empUuidDto.getEmployeeUuid1());
                if (employeeUuidList.contains(empUuidDto.getEmployeeUuid1())) {
                    employeeUuidList.remove(empUuidDto.getEmployeeUuid1());
                }
                empUniqueUuidList.add(companyUuid + "_" + empUuidDto.getEmployeeUuid1());
            }
            Query query = new Query().addCriteria(Criteria.where("companyUuid").is(companyUuid));
            query.addCriteria(Criteria.where("employeeUuid").in(employeeUuidList));
            if (mongoTemplate.count(query, Employee.class) > 0) {
                employeeList = mongoTemplate.find(query, Employee.class);
                for (String s : employeeUuidList) {
                    empUniqueUuidList.add(companyUuid + "_" + s);
                }
            }
            if (Objects.nonNull(fixedEmployee)) {
                employeeList.add(0, fixedEmployee);
            }
        } else {
            Employee employee = employeeRepository.findByEmployeeUniqueUuid(employeeUniqueUuid);
            if (employee != null) {
                employeeList.add(employee);
                empUniqueUuidList.add(employeeUniqueUuid);
            }
        }
        List<AppointmentEmpListDto> empListDtoList = new LinkedList<>();
        if (!CollectionUtils.isEmpty(employeeList)) {
            Map<String, String> employeeLabelMap = getEmpLabelMap();
            Criteria criteria = Criteria.where("employeeUniqueUuid").in(empUniqueUuidList)
                    .and("appointmentTime").is(queryDto.getAppointmentTime())
                    .and("status").is(0);
            Query query = new Query(criteria);
            List<Appointment> appointmentList = new ArrayList<>();
            if (mongoTemplate.count(query, Appointment.class) > 0) {
                appointmentList = mongoTemplate.find(query, Appointment.class);
            }
            Set<String> empUniqueUuidSet = appointmentList.stream().map(Appointment::getEmployeeUniqueUuid).collect(Collectors.toSet());
            for (int i = 0; i < employeeList.size(); i++) {
                Employee employee = employeeList.get(i);
                AppointmentEmpListDto empListDto = appointmentMapper.empDomainToAppointmentDto(employee);
                //主推经纪人排在首位
                empListDto.setCurrentRecommend(i == 0 ? true : false);
                //标签uuid转文字
                empListDto.setLabelContentList(getLabelContentList(employeeLabelMap, employee.getLabelUuidList()));
                //设置工龄展示文案
                empListDto.setWorkAge(DateTypeUtil.getWorkAgeStr(employee.getAttendWorkTime()));
                //当前经纪人当前时段是否可预约
                empListDto.setReducible(empUniqueUuidSet.contains(employee.getEmployeeUniqueUuid()) ? false : true);

                empListDtoList.add(empListDto);
            }
        }
        return empListDtoList;
    }

    @Override
    public List<AppointmentEmpAdminListDto> getAdminEmpList(AppointmentEmpAdminQueryDto queryDto) {
        ShowEmpUuidDto empUuidDto;
        if (queryDto.getBusinessType() == 1) {
            empUuidDto = employeeService.getEmployeeUuidDtoByFirsthand(queryDto.getBusinessUuid());
        } else {
            empUuidDto = employeeService.getEmployeeUuidDtoByProperty(queryDto.getBusinessUuid());
        }
        String companyUuid = empUuidDto.getCompanyUuid();
        List<String> employeeUuidList = empUuidDto.getEmployeeUuidList();
        String fixedEmployeeUuid = empUuidDto.getFixedEmployeeUuid();

        //获取固定展示位经纪人
        Employee fixedEmployee = employeeRepository.findByCompanyUuidAndEmployeeUuid(companyUuid, fixedEmployeeUuid);
        if (employeeUuidList.contains(fixedEmployeeUuid)) {
            employeeUuidList.remove(fixedEmployeeUuid);
        }
        if (fixedEmployee == null) {
            fixedEmployee = employeeRepository.findByCompanyUuidAndEmployeeUuid(companyUuid, empUuidDto.getEmployeeUuid1());
            if (employeeUuidList.contains(empUuidDto.getEmployeeUuid1())) {
                employeeUuidList.remove(empUuidDto.getEmployeeUuid1());
            }
        }
        Query query = new Query().addCriteria(Criteria.where("companyUuid").is(companyUuid));
        query.addCriteria(Criteria.where("employeeUuid").in(employeeUuidList));
        List<Employee> employeeList = new LinkedList<>();
        if (mongoTemplate.count(query, Employee.class) > 0) {
            employeeList = mongoTemplate.find(query, Employee.class);
        }
        employeeList.add(0, fixedEmployee);
        List<AppointmentEmpAdminListDto> empListDtoList = new LinkedList<>();
        for (Employee employee : employeeList) {
            AppointmentEmpAdminListDto empListDto = AppointmentEmpAdminListDto.builder()
                    .employeeName(employee.getEmployeeName())
                    .employeeUniqueUuid(employee.getEmployeeUniqueUuid())
                    .build();
            empListDtoList.add(empListDto);
        }
        return empListDtoList;
    }

    @Override
    public List<AppointmentEmpAdminListDto> getV20AdminEmpList(AppointmentEmpAdminQueryDto queryDto) {
        //查房源
        Property property = propertyRepository.findFirstByPropertyUniqueUuid(queryDto.getBusinessUuid());
        if (property == null) {
            log.info("property is null propertyUniqueUuid:{}", queryDto.getBusinessUuid());
            throw new BusinessException("property is null");
        }
        //返回列表 员工列表uuid
        ShowEmpUuidDto showEmpUuidDto = employeeService.getV20EmployeeUuidDtoByProperty(queryDto.getBusinessUuid());
        if (showEmpUuidDto == null) {
            throw new BusinessException("该房源无经纪人列表");
        }
        List<String> employeeUuidList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(showEmpUuidDto.getEmployeeUuidList())){
            employeeUuidList.addAll(showEmpUuidDto.getEmployeeUuidList());
            if (!showEmpUuidDto.getEmployeeUuidList().contains(showEmpUuidDto.getFixedEmployeeUuid())) {
                employeeUuidList.add(0,showEmpUuidDto.getFixedEmployeeUuid());
            }
        }

        Query query = new Query().addCriteria(Criteria.where("companyUuid").is(property.getCompanyUuid()));
        query.addCriteria(Criteria.where("employeeUuid").in(employeeUuidList));
        List<Employee> employeeList = new LinkedList<>();
        if (mongoTemplate.count(query, Employee.class) > 0) {
            employeeList = mongoTemplate.find(query, Employee.class);
        }
        List<AppointmentEmpAdminListDto> empListDtoList = new LinkedList<>();
        for (Employee employee : employeeList) {
            AppointmentEmpAdminListDto empListDto = AppointmentEmpAdminListDto.builder()
                    .employeeName(employee.getEmployeeName())
                    .employeeUniqueUuid(employee.getEmployeeUniqueUuid())
                    .build();
            empListDtoList.add(empListDto);
        }
        return empListDtoList;
    }

    @Override
    public void submitAppointment(AppointmentSubmitDto submitDto) {
        //校验当前时间当前经纪人是否可预约
        Criteria criteriaEmp = Criteria.where("employeeUniqueUuid").is(submitDto.getEmployeeUniqueUuid())
                .and("appointmentTime").is(submitDto.getAppointmentTime())
                .and("status").is(0);
        if (mongoTemplate.count(new Query(criteriaEmp), Appointment.class) > 0) {
            throw new BusinessException(submitDto.getEmployeeName() + "同时段已有其他预约，请刷新页面重新选择！");
        }
        Criteria criteriaMember = Criteria.where("memberId").is(submitDto.getMemberId())
                .and("appointmentTime").is(submitDto.getAppointmentTime())
                .and("status").is(0);
        if (mongoTemplate.count(new Query(criteriaMember), Appointment.class) > 0) {
            throw new BusinessException("您在同时段已有其他预约，请重新选择预约时间！");
        }
        Criteria criteriaHouse = Criteria.where("memberId").is(submitDto.getMemberId())
                .and("businessType").is(submitDto.getBusinessType())
                .and("businessUuid").is(submitDto.getBusinessUuid())
                .and("status").is(0);
        if (mongoTemplate.count(new Query(criteriaHouse), Appointment.class) > 0) {
            throw new BusinessException("您已预约过此房源，不可重复提交！");
        }

        Appointment appointment = appointmentMapper.submitDtoToDomain(submitDto);
        appointment.setStatus(0);
        appointment.setCreateTime(new Date());
        appointment.setCityCode(QfContextHolder.getContext().getCityCode());
        appointment.setCorporationCode(QfContextHolder.getContext().getCorporationCode());
        repository.save(appointment);
        sentAppointmentMessage(submitDto);
    }

    /**
     * 调用fyapi发送情报
     */
    private void sentAppointmentMessage(AppointmentSubmitDto submitDto) {
        //发送预约邮件给经纪人
        QfContext context = QfContextHolder.getContext();
        Corporation corporation = corporationService.getCorporationByCorporationCode(context.getCorporationCode());
        if (corporation == null) {
            throw new BusinessException("集团不存在,预约消息发送失败");
        }
        String appId = corporation.getPullAppId();
        String appKey = corporation.getPullAppKey();
        String domain = corporation.getPullDomain();

        String companyUuid;
        String propertyNo = null;
        //这里应该获取房源的companyUuid来传入fyapi
        if (submitDto.getBusinessType().equals(1)) {
            FirsthandEstate firsthandEstate = firsthandEstateRepository.findFirstByEstateUniqueUuidAndCorporationCode(submitDto.getBusinessUuid(), context.getCorporationCode());
            if (firsthandEstate == null) {
                return;
            }
            companyUuid = firsthandEstate.getCompanyUuid();
        } else {
            Property property = propertyRepository.findByCorporationCodeAndPropertyUniqueUuid(context.getCorporationCode(), submitDto.getBusinessUuid());
            if (property == null) {
                return;
            }
            companyUuid = property.getCompanyUuid();
            propertyNo = property.getPropertyNo();
        }

        HttpHeaders headers = getHeaders(companyUuid, appId, appKey);
        String businessType = "";
        switch (submitDto.getBusinessType()) {
            case 1:
                businessType = "新房";
                break;
            case 2:
                businessType = "二手房";
                break;
            case 3:
                businessType = "租房";
                break;
        }

        AppointmentMessageRequest request = new AppointmentMessageRequest();
        request.setCompanyUuid(companyUuid);
        request.setEmployeeUuid(submitDto.getEmployeeUniqueUuid().replace(companyUuid + "_", ""));
        request.setEmployeeName(submitDto.getEmployeeName());
        request.setAppointmentName(submitDto.getAppointmentName());
        request.setAppointmentPhone(submitDto.getAppointmentPhone());
        request.setVisitorNum(submitDto.getVisitorNum());
        request.setAppointmentTime(submitDto.getAppointmentTime());
        request.setBusinessType(businessType);
        request.setPropertyUuid(submitDto.getBusinessUuid().replace(companyUuid + "_", ""));
        request.setPropertyNo(propertyNo);

        if (commonService.isV20Corporation()) {
            sentV20AppointmentMessage(request);
            return;
        }

        try {
            ResponseEntity<JSONObject> jsonObjectResponseEntity = restTemplate.postForEntity(domain + APPOINTMENT_MESSAGE_API, new HttpEntity<>(request, headers), JSONObject.class);
            System.out.println(1);
        } catch (RestClientException e) {
            log.info("发送预约情报失败:{}", JSONObject.toJSONString(e));
        }
        log.info("发送消息响应:{}", JSONObject.toJSONString(1));
    }

    private void sentV20AppointmentMessage(AppointmentMessageRequest request) {

        HttpHeaders headers = new HttpHeaders();
        headers.add("companyUuid", request.getCompanyUuid());

        String title = request.getBusinessType() + "预约看房提醒";

        StringBuffer contents = new StringBuffer();
        contents.append("预约人姓名：").append(request.getAppointmentName());
        contents.append("<br/>预约电话：").append(request.getAppointmentPhone());
        contents.append("<br/>随访人数：").append(request.getVisitorNum());
        contents.append("<br/>预约时间：").append(request.getAppointmentTime());
        contents.append("<br/>请及时联系用户看房!");

        if (StringUtils.equals(NEW_HOUSE, request.getBusinessType())) {
            contents.append("<br/>关联楼盘：<qfLink urlKey='" + request.getPropertyUuid() + "' urlType='newhouse_detail'>点击查看</qfLink>");
        } else {
            contents.append("<br/>关联房源：<qfLink urlKey='" + request.getPropertyUuid() + "' urlType='property_detail'>" + request.getPropertyNo() + "</qfLink>");
        }

        //组装消息
        CreateMessageDTO dto = new CreateMessageDTO();
        dto.setRemindModeEnum(RemindModeEnum.SIDE_MESSAGE);
        dto.setMessageTypeEnum(MessageTypeEnum.BUSINESS_MESSAGE);
        dto.setSender(MSG_TRIGGER_SYS);

        ReceiverDTO receiverDTO = new ReceiverDTO();
        receiverDTO.setReceiverType(ReceiverTypeEnum.EMPLOYEE);
        receiverDTO.setReceiverUuids(Lists.newArrayList(request.getEmployeeUuid()));

        dto.setReceiverDTOList(Lists.newArrayList(receiverDTO));
        dto.setTitle(title);
        dto.setContent(contents.toString());
        dto.setRemind(true);
        dto.setSubMessageType("WECHATAPP");
        dto.setSubTitle(MESSAGE_SUB_TITLE);
        dto.setBusinessUuid(request.getPropertyUuid());

        V20MessageDto v20MessageDto = new V20MessageDto();
        v20MessageDto.setCreateMessageDTO(dto);
        try {
            JSONObject jsonObject = gatewayTemplate.postForObject(V20_SENT_SINGLE_MESSAGE_API, v20MessageDto, headers, JSONObject.class);
        } catch (Exception e) {
            log.error("sent V20Appointment Message error:{}", e);
            throw new BusinessException("预约看房发送20消息失败");
        }
    }

    @Override
    public Page<MyAppointmentListDto> getMyAppointmentList(MyAppointmentQueryDto queryDto, Pageable pageable) {
        Query query = createFindQuery(queryDto);
        long count = mongoTemplate.count(query, Appointment.class);
        List<Appointment> list = new ArrayList<>();
        if (count > 0) {
            list = mongoTemplate.find(query.with(pageable), Appointment.class);
        }
        return PageableExecutionUtils.getPage(appointmentMapper.domainToMyListDto(list), pageable, () -> count);
    }

    @Override
    public void cancelAppointment(String id) {
        Criteria criteria = Criteria.where("id").is(id).and("status").is(0);
        Update update = new Update();
        update.set("status", 2);
        update.set("updateTime", new Date());
        mongoTemplate.updateFirst(new Query(criteria), update, Appointment.class);
    }

    @Override
    public void affirmAppointment(AppointmentOpDto opDto) {
        Criteria criteria = Criteria.where("id").is(opDto.getId()).and("status").is(0);
        Update update = new Update();
        update.set("status", 1);
        update.set("visitTime", opDto.getVisitTime());
        update.set("updateTime", new Date());
        mongoTemplate.updateFirst(new Query(criteria), update, Appointment.class);
    }

    private Query createFindQuery(MyAppointmentQueryDto queryDto) {
        Query query = new Query();
        if (queryDto.getUserType() == 1) {
            query.addCriteria(Criteria.where("memberId").is(queryDto.getUserId())
                    .and("status").is(queryDto.getStatus()));
        } else {
            query.addCriteria(Criteria.where("employeeUniqueUuid").is(queryDto.getUserId())
                    .and("status").is(queryDto.getStatus()));
        }
        switch (queryDto.getStatus()) {
            case 0:
                query.with(Sort.by(Sort.Order.asc("appointmentTime")));
                break;
            case 1:
                query.with(Sort.by(Sort.Order.desc("visitTime")));
                break;
            case 2:
                query.with(Sort.by(Sort.Order.desc("updateTime")));
                break;
        }

        return query;
    }

    @Override
    public List<String> getLabelContentList(Map<String, String> employeeLabelMap, List<String> labelUuidList) {
        List<String> labelContentList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(labelUuidList)) {
            for (String s : labelUuidList) {
                String labelContent = employeeLabelMap.get(s);
                if (StringUtils.isNotEmpty(labelContent)) {
                    labelContentList.add(labelContent);
                }
            }
        }
        return labelContentList;
    }

    @Override
    public Map<String, String> getEmpLabelMap() {
        Corporation corporation = corporationService.getCorporationByCorporationCode(QfContextHolder.getContext().getCorporationCode());
        List<EmployeeLabel> employeeLabelList = corporation.getEmployeeLabelList();
        Map<String, String> employeeLabelMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(employeeLabelList)) {
            employeeLabelMap = employeeLabelList.stream().collect(Collectors.toMap(EmployeeLabel::getLabelUuid, EmployeeLabel::getLabelContent, (k1, k2) -> k1));
        }
        return employeeLabelMap;
    }

    @Override
    public List<NewEntrustSimpleDto> newAppointmentList(String employeeUniqueUuid) {
        MyAppointmentQueryDto queryDto = MyAppointmentQueryDto.builder()
                .userType(2)
                .status(0)
                .userId(employeeUniqueUuid)
                .build();
        List<MyAppointmentListDto> content = getMyAppointmentList(queryDto, PageRequest.of(0, 4)).getContent();
        List<NewEntrustSimpleDto> result = new LinkedList<>();
        if (!CollectionUtils.isEmpty(content)) {
            for (MyAppointmentListDto dto : content) {
                String showInfo = dto.getAppointmentName() + " 预约" + dto.getAppointmentTime() + "看房，共" + dto.getVisitorNum() + "人随行";
                result.add(NewEntrustSimpleDto.builder()
                        .businessType(dto.getBusinessType())
                        .showInfo(showInfo)
                        .build());
            }
        }
        return result;
    }

    /**
     * 获取所有预约信息
     *
     * @param appointmentQueryDto 查询条件
     * @param pageable            分页参数
     * @return
     */
    @Override
    public Page<AppointmentResponseDto> getAppointmentList(AppointmentQueryDto appointmentQueryDto, Pageable pageable) {
        String searchStr = appointmentQueryDto.getSearchStr();
        Date beginCreateTime = null;
        Date endCreateTime = null;
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Query query = new Query();

        //公共查询条件
        query.addCriteria(Criteria.where("corporationCode").is(appointmentQueryDto.getCorporationCode()));

        //筛选查询条件
        if (appointmentQueryDto.getBeginCreateTime() != null && appointmentQueryDto.getEndCreateTime() != null) {
            try {
                beginCreateTime = format.parse(appointmentQueryDto.getBeginCreateTime() + BEGIN_TIME);
                endCreateTime = format.parse(appointmentQueryDto.getEndCreateTime() + END_TIME);
            } catch (ParseException e) {
                log.error("日期转换错误：", e);
            }
            query.addCriteria(Criteria.where("createTime").gte(beginCreateTime).lt(endCreateTime));
        }
        if (appointmentQueryDto.getBeginAppointmentTime() != null && appointmentQueryDto.getEndAppointmentTime() != null) {
            query.addCriteria(Criteria.where("appointmentTime").gte(appointmentQueryDto.getBeginAppointmentTime() + BEGIN_TIME).lt(appointmentQueryDto.getEndAppointmentTime() + END_TIME));
        }
        if (appointmentQueryDto.getBeginVisitTime() != null && appointmentQueryDto.getEndVisitTime() != null) {
            query.addCriteria(Criteria.where("visitTime").gte(appointmentQueryDto.getBeginVisitTime() + BEGIN_TIME).lt(appointmentQueryDto.getEndVisitTime() + END_TIME));
        }
        if (StringUtils.isNotEmpty(appointmentQueryDto.getCityCode())) {
            query.addCriteria(Criteria.where("cityCode").is(appointmentQueryDto.getCityCode()));
        } else if (!CollectionUtils.isEmpty(appointmentQueryDto.getCityCodes())) {
            query.addCriteria(Criteria.where("cityCode").in(appointmentQueryDto.getCityCodes()));
        }

        if (appointmentQueryDto.getBusinessType() != null) {
            query.addCriteria(Criteria.where("businessType").is(appointmentQueryDto.getBusinessType()));
        }
        if (appointmentQueryDto.getStatus() != null) {
            query.addCriteria(Criteria.where("status").is(appointmentQueryDto.getStatus()));
        }
        if (StringUtils.isNotEmpty(searchStr)) {
            Criteria criteria = new Criteria();
            criteria.orOperator(
                    Criteria.where("memberPhone").regex(".*?" + searchStr + ".*"),
                    Criteria.where("appointmentName").regex(".*?" + searchStr + ".*"),
                    Criteria.where("businessName").regex(".*?" + searchStr + ".*"),
                    Criteria.where("appointmentPhone").regex(".*?" + searchStr + ".*"),
                    Criteria.where("employeeName").regex(".*?" + searchStr + ".*"));
            query.addCriteria(criteria);
        }

        query.with(Sort.by(Sort.Order.desc("createTime")));

        long count = mongoTemplate.count(query, Appointment.class);
        List<Appointment> appointments = new ArrayList<>();
        if (count > 0) {
            appointments = mongoTemplate.find(query.with(pageable), Appointment.class);
        }
        return PageableExecutionUtils.getPage(appointmentMapper.domainToAppointmentResponseDto(appointments), pageable, () -> count);
    }

    /**
     * 根据修改预约信息
     *
     * @param appointmentEditDto
     */
    @Override
    public void editAppointment(AppointmentEditDto appointmentEditDto) {
        Appointment appointment = mongoTemplate.findById(appointmentEditDto.getId(), Appointment.class);
        if (appointment == null) {
            throw new BusinessException("编辑失败！");
        }

        appointment.setEmployeeUniqueUuid(appointmentEditDto.getEmployeeUniqueUuid());
        appointment.setEmployeeName(appointmentEditDto.getEmployeeName());
        if (appointmentEditDto.getStatus() == 1) {
            appointment.setStatus(1);
            appointment.setVisitTime(appointmentEditDto.getVisitTime());
        }
        if (appointmentEditDto.getStatus() == 0) {
            appointment.setStatus(0);
            appointment.setVisitTime(null);
        }
        if (appointmentEditDto.getStatus() == 2) {
            appointment.setStatus(2);
            appointment.setVisitTime(null);
        }
        appointment.setUpdateTime(new Date());
        repository.save(appointment);
    }

    private HttpHeaders getHeaders(String companyUuid, String appId, String appKey) {
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        headers.add("X-AUTH-APP-ID", appId);
        headers.add("X-AUTH-KEY", appKey);
        headers.add("companyUuid", companyUuid);
        log.info("========>headers:{}", JSON.toJSONString(headers));
        return headers;
    }
}
